package fr.umlv.m2.jee.spij.service.schedule.education;

import fr.umlv.m2.jee.spij.persistence.education.*;
import fr.umlv.m2.jee.spij.persistence.education.dao.HibernateFieldWorkDAO;
import fr.umlv.m2.jee.spij.persistence.education.dao.HibernateLessonDAO;
import fr.umlv.m2.jee.spij.persistence.education.dao.HibernateTutorialDAO;
import fr.umlv.m2.jee.spij.persistence.education.dao.HibernateUnitDAO;
import fr.umlv.m2.jee.spij.service.ldap.authentification.DisplayActor;
import fr.umlv.m2.jee.spij.service.schedule.Assignment;
import org.richfaces.model.CalendarDataModel;
import org.richfaces.model.CalendarDataModelItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * .
 *
 * @author thomas magny
 */
@Component("calendarDataModelEducationImpl")
public class CalendarDataModelEducationImpl
        implements CalendarDataModel, Assignment {

    /**
     * Calendar.
     */
    private final Calendar calendar = Calendar.getInstance();

    /**
     * displayed list.
     */
    private final List<Education> educationList = new ArrayList<Education>();

    /**
     * Actor.
     */
    private DisplayActor actor;

    /**
     * The unit DAO.
     */
    @Autowired
    private HibernateUnitDAO unitDAO;

    /**
     * The lesson DAO.
     */
    @Autowired
    private HibernateLessonDAO lessonDAO;

    /**
     * The fieldwork DAO.
     */
    @Autowired
    private HibernateFieldWorkDAO fieldWorkDAO;

    /**
     * The tutorial DAO.
     */
    @Autowired
    private HibernateTutorialDAO tutorialDAO;

    /**
     * Stores data.
     */
    private void storeData() {
        educationList.clear();

        final List<Unit> units = unitDAO.findAll();

        for (Unit unit : units) {
            final List<FieldWork> fieldWorkList =
                    fieldWorkDAO.findByLdapActorAndUnitId(
                            unit.getId(),
                            actor.getLogin(),
                            actor.getType());
            if (fieldWorkList != null) {
                educationList.addAll(fieldWorkList);
            }
            final List<Lesson> lessonList =
                    lessonDAO.findByLdapActorAndUnitId(
                            unit.getId(),
                            actor.getLogin(),
                            actor.getType());
            if (lessonList != null) {
                educationList.addAll(lessonList);
            }
            final List<Tutorial> tutorialList =
                    tutorialDAO.findByLdapActorAndUnitId(
                            unit.getId(),
                            actor.getLogin(),
                            actor.getType());
            if (tutorialList != null) {
                educationList.addAll(tutorialList);
            }
        }
    }

    /**
     * Sets the user.
     *
     * @param newActor the actor.
     */
    @Override
    public final void setUser(final DisplayActor newActor) {
        this.actor = newActor;
    }

    /**
     * Gets the item that is displayed into the calendar.
     *
     * @param dates the dates that are currently displayed.
     *
     * @return the {@code CalendarDataModelItem}.
     */
    @Override
    @Transactional(readOnly = true)
    public final CalendarDataModelItem[] getData(final Date[] dates) {
        storeData();

        final CalendarDataModelItem[] calendarDataModelItems =
                new CalendarDataModelItem[dates.length];

        for (int i = 0; i < dates.length; i++) {
            calendar.setTime(dates[i]);

            CalendarDataModelEducationItemImpl item =
                    new CalendarDataModelEducationItemImpl();

            for (Education education : educationList) {
                if (education.getDuration().getStart().dayOfYear().get()
                        == calendar.get(Calendar.DAY_OF_YEAR)) {
                    addDataModelItem(item, education);
                }
            }
            calendarDataModelItems[i] = item;
        }
        return calendarDataModelItems;
    }

    /**
     * Adds data into the item.
     *
     * @param item      the item.
     * @param education the Education.
     */
    private void addDataModelItem(final CalendarDataModelEducationItemImpl item,
                                  final Education education) {
        item.addData(education.getSubject());

        item.setDay(calendar.get(Calendar.DAY_OF_MONTH));
        item.setEnabled(true);
        item.setStyleClass("");
    }

    /**
     * @param date the date.
     *
     * @return the tooltip object.
     */
    @Override
    public final Object getToolTip(final Date date) {
        return "toto tooltip";
    }
}
